package com.alibaba.citrus.ots.application.report.ability.facade.service;

import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.crplatformenhance.api.customersalescopequery.dto.QuerySaleScopeByIdRequest;
import com.epoch.app.crplatformenhance.api.customersalescopequery.service.CustomerSaleScopeQueryService;
import com.epoch.app.crplatformenhance.sdo.CustomerSaleScopeSDO;
import com.epoch.app.otsapplicationadaptersdk.model.dto.CustomerCreditData;
import com.epoch.app.otsapplicationadaptersdk.model.dto.CustomerCreditSyncQueryResponse;
import com.epoch.app.otsapplicationadaptersdk.model.dto.RestSyncQueryCustomerCreditRequest;
import com.epoch.app.otsapplicationadaptersdk.model.dto.SyncQueryCustomerCreditData;
import com.epoch.app.otsapplicationadaptersdk.model.dto.SyncQueryCustomerCreditRule;
import com.epoch.app.otsapplicationadaptersdk.service.OtsApplicationAdapterSdkService;
import com.epoch.app.otsapplicationreportsdk.customercreditread.dto.QueryRequest;
import com.epoch.app.otsapplicationreportsdk.customercreditread.service.CustomerCreditReadService;
import com.epoch.app.otsapplicationreportsdk.model.dto.CustomerCreditQueryResponse;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;

/**
 * @description: 客户信贷余额查询
 * @author: yuhw
 * @date: 2023年09月26日 11:47
 **/
@Component
public class CustomerCreditReadServiceImpl implements CustomerCreditReadService {
    private static Log log = Log.getLogger(CustomerCreditReadServiceImpl.class);

    @Resource
    private OtsApplicationAdapterSdkService otsApplicationAdapterSdkService;
    @Resource
    private CustomerSaleScopeQueryService customerSaleScopeQueryService;

    //乌鲁木齐蒙牛乳业销售组织
    private static final String SALE_ORG_CODE = "6105";
    //负号
    private static final String NEGATIVE = "-";

    private static final String YYYY_MM_DD = "yyyy-MM-dd";

    @Override
    @FacadeInvoker(value = "客户信贷余额查询")
    public Result<CustomerCreditQueryResponse> query(QueryRequest queryRequest) {
        this.checkParams(queryRequest);
        //权限校验
        //获取分配了当前登录人的售达方列表, 看当前选择的售达方是否存在于该范围内, 若不在则提示没有权限
//        Result<List<CustomerSaleScopeSDO>> listResult = otsApplicationReportSdkService.queryCustomerSaleScopeListByLoginUser();
//        CustomerSaleScopeSDO customerSaleScopeSDO = Nullable.stream(listResult.getResult()).filter(sdo -> sdo.getId().equals(queryRequest.getCustomerId())).findFirst().orElse(null);
//        if (customerSaleScopeSDO == null){
//            throw new FacadeException("OTS-03-005-00-15-300");
//        }
        QuerySaleScopeByIdRequest querySaleScopeByIdRequest = new QuerySaleScopeByIdRequest();
        querySaleScopeByIdRequest.setId(queryRequest.getCustomerId());
        Result<CustomerSaleScopeSDO> customerSaleScopeSDOResult = customerSaleScopeQueryService.querySaleScopeById(querySaleScopeByIdRequest);
        log.info("CustomerCreditReadServiceImpl_querySaleScopeById_result:{}", JSON.toJSONString(customerSaleScopeSDOResult));
        if (customerSaleScopeSDOResult == null || customerSaleScopeSDOResult.getResult() == null){
            throw new FacadeException("OTS-03-005-00-15-300");
        }
        CustomerSaleScopeSDO customerSaleScopeSDO = customerSaleScopeSDOResult.getResult();
        //根据页面传入的客户id 查询客户信息, 获取到客户编码 分销渠道
        //组装查询SAP客户信贷的请求参数
        RestSyncQueryCustomerCreditRequest restSyncQueryCustomerCreditRequest = this.buildRestSyncQueryCustomerCreditRequest(customerSaleScopeSDO);
        try {
            //请求SAP查询客户信贷
//            restSyncQueryCustomerCreditRequest.getData().setVTWEG("A2");
            log.info("CustomerCreditReadServiceImpl_restSyncQueryCustomerCredit_request:{}",JSON.toJSONString(restSyncQueryCustomerCreditRequest));
            Result<CustomerCreditSyncQueryResponse> queryResponseResult = otsApplicationAdapterSdkService.restSyncQueryCustomerCredit(restSyncQueryCustomerCreditRequest);
            log.info("CustomerCreditReadServiceImpl_restSyncQueryCustomerCredit_result:{}",JSON.toJSONString(queryResponseResult));
            if (queryResponseResult == null || queryResponseResult.getResult() == null ||
                    CollectionUtils.isEmpty(queryResponseResult.getResult().getData())){
                return Result.success(null);
            }
            return Result.success(buildCustomerCreditQueryResponse(queryResponseResult.getResult()));
        }catch (Throwable e){
            log.error("CustomerCreditReadServiceImpl_restSyncQueryCustomerCredit_error",e);
            throw new FacadeException("OTS-03-005-00-15-303");
        }
    }

    //校验页面入参
    private void checkParams(QueryRequest request){
        if (request == null){
            throw new FacadeException("OTS-03-005-00-15-301");
        }
        if (StringUtils.isBlank(request.getCustomerId())){
            throw new FacadeException("OTS-03-005-00-15-302");
        }
//        Optional.ofNullable(request.getCustomerId()).orElseThrow(() -> new FacadeException(""));
//        if (StringUtils.isBlank(request.getQueryDate())){
//            throw new FacadeException("");
//        }
//        SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DD);
//        try {
//            Date parse = sdf.parse(request.getQueryDate());
//        } catch (ParseException e) {
//            log.error("CustomerCreditReadServiceImpl_date_parse_error",e);
//            throw new FacadeException("");
//        }
    }

    /**
     * 构建同步请求客户信息请求入参
     */
    private RestSyncQueryCustomerCreditRequest buildRestSyncQueryCustomerCreditRequest(CustomerSaleScopeSDO customerSaleScopeSDO){
        RestSyncQueryCustomerCreditRequest syncQueryCustomerCreditRequest = new RestSyncQueryCustomerCreditRequest();
        SyncQueryCustomerCreditData data = new SyncQueryCustomerCreditData();
        //分子公司编码 默认 6105
        data.setVKORG(SALE_ORG_CODE);
        //TODO 看需要可以在这里加一个销售组织id转编码的
//        customerSaleScopeSDO.getOrgSalesOrganizationCode2()
//        分销渠道
        data.setVTWEG(customerSaleScopeSDO.getChannelCode());
        //查询规则
        SyncQueryCustomerCreditRule rule = new SyncQueryCustomerCreditRule();
        rule.setSIGN("I");
        rule.setOPTION("EQ");
        //客户编码
        rule.setLOW(customerSaleScopeSDO.getCustomerCode());
        data.setKUNNR(rule);
        syncQueryCustomerCreditRequest.setData(data);
        return syncQueryCustomerCreditRequest;
    }

    /**
     * 构建页面返回
     * @param syncQueryResponse
     * @return
     */
    private CustomerCreditQueryResponse buildCustomerCreditQueryResponse(CustomerCreditSyncQueryResponse syncQueryResponse){
        //因为客户有属于不同信贷范围的信贷余额,这里需要过滤出新疆的数据
        CustomerCreditData data = syncQueryResponse.getData().stream().filter(customerCreditData -> SALE_ORG_CODE.equals(customerCreditData.getKKBER())).findFirst().orElse(new CustomerCreditData());
        CustomerCreditQueryResponse response = new CustomerCreditQueryResponse();
        //售达方编码
        response.setSoldPartCode(data.getKUNNR());
        //客户名称全称
        response.setCustomerFullName(data.getNAME1());
        //信贷范围
        response.setCreditScope(data.getKKBER());
        //信贷额度
        response.setCreditLimit(data.getKLIMK());
        //销售值
        response.setSalesValue(data.getSAUFT());
        //应收总额
        response.setReceivableBalance(data.getSKFOR());
        //信贷风险总额
        response.setTotalCreditBalance(data.getSUM_OPENS());
        //剩余信贷余额
        response.setRemainingCreditBalance(data.getDELTA_TO_LIMIT());
        //费用余额
        response.setFeeBalance(data.getZFAMT4());
        //待扣余额
        response.setToBeDeductedBalance(data.getZFAMT3());
        //冻结订单金额
        response.setFreezeOrderAmount(data.getKZWI1());
        //参考总余额
        response.setReferenceTotalBalance(data.getREF_AM());
        //负号倒转, SAP的负号在字符串末尾
        reverseNegative(response);
        return response;
    }

    //负号倒转
    private String changeNegativePosition(String number){
        return NEGATIVE + number.replaceAll(NEGATIVE,"");
    }

    private void reverseNegative(Object data){
        if (data == null){
            return;
        }
        Class<?> clazz = data.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.getType() == String.class){
                try {
                    String v = (String) field.get(data);
                    if (StringUtils.isNotBlank(v) && v.contains(NEGATIVE)){
                        field.set(data,changeNegativePosition(v));
                    }
                } catch (IllegalAccessException e) {
                    continue;
                }
            }
        }
    }
}
